# -*- coding: utf-8 -*-
"""
@Project    :demo
@File       :test31.py
@IDE        :PyCharm
@Author     :Tao
@Date       :2024/3/22 17:13
@Description: 泛型函数的测试
"""

# coding: utf-8
from functools import singledispatch, update_wrapper


class singledispatchmethod:
    """Single-dispatch generic method descriptor.

    Supports wrapping existing descriptors and handles non-descriptor
    callables as instance methods.
    """

    def __init__(self, func):
        if not callable(func) and not hasattr(func, "__get__"):
            raise TypeError(f"{func!r} is not callable or a descriptor")

        self.dispatcher = singledispatch(func)
        self.func = func

    def register(self, cls, method=None):
        """generic_method.register(cls, func) -> func

        Registers a new implementation for the given *cls* on a *generic_method*.
        """
        return self.dispatcher.register(cls, func=method)

    def __get__(self, obj, cls=None):
        def _method(*args, **kwargs):
            if args:
                method = self.dispatcher.dispatch(args[0].__class__)
            else:
                method = self.func
                for v in kwargs.values():
                    if v.__class__ in self.dispatcher.registry:
                        method = self.dispatcher.dispatch(v.__class__)
                        if method is not self.func:
                            break

            return method.__get__(obj, cls)(*args, **kwargs)

        _method.__isabstractmethod__ = self.__isabstractmethod__
        _method.register = self.register
        update_wrapper(_method, self.func)
        return _method

    @property
    def __isabstractmethod__(self):
        return getattr(self.func, '__isabstractmethod__', False)


class TestDemo(object):

    @singledispatch
    def __init__(self, int_a: int):
        self.a = int_a

    @__init__.register(list)
    def _(self, list_a: list):
        print(list_a)
        self.list_a = list_a


if __name__ == "__main__":
    a = 1
    list_a = [1, 2, 3]

    test_demo = TestDemo(list_a)
    print(test_demo.list_a)




